"""
聊天服务
整合LLM、情感分析和TTS功能，提供统一的聊天接口
保持原有的返回数据结构，确保前端兼容性
"""

import json
import logging
import asyncio
from typing import List, Dict, Any, Optional, AsyncGenerator
from pydantic import BaseModel

from .llm_client import llm_client, ChatMessage
# emotion_analyzer功能已集成到其他服务中
from .minmax_service import MinMaxService
from ..utils.performance_utils import merge_voice_settings, should_include_emotion
from ..core.config import settings

logger = logging.getLogger(__name__)


class ChatRequest(BaseModel):
    """聊天请求模型（保持与原版本一致）"""
    messages: List[ChatMessage]
    session_id: Optional[str] = None
    stream: Optional[bool] = False
    generate_voice: Optional[bool] = False
    chatId: Optional[int] = None
    chat_id: Optional[int] = None
    include_emotion: Optional[bool] = False
    language: Optional[str] = None
    reserve_id: Optional[str] = None
    uuid: Optional[str] = None

    class Config:
        populate_by_name = True
        json_schema_extra = {
            "example": {
                "messages": [{"role": "user", "content": "你好"}],
                "stream": True,
                "generate_voice": True,
                "chatId": 1,
                "include_emotion": False,
                "reserve_id": "2abcd28a-b8d1-4ac9-8d59-821b5f9cde6c",
                "uuid": "550e8400-e29b-41d4-a716-446655440000"
            }
        }


class ChatResponse(BaseModel):
    """聊天响应模型（保持与原版本一致）"""
    text: str
    audio: Optional[Dict[str, Any]] = None
    qx: Dict[str, float]
    session_id: str
    history: List[Dict[str, str]]


class ChatService:
    """
    聊天服务
    整合各个子服务，提供统一的聊天接口
    严格保持原有的返回数据结构
    """
    
    def __init__(self):
        self.llm_client = llm_client
        self.tts_service = MinMaxService()
        
    async def process_chat(
        self,
        messages: List[Dict[str, str]],
        session_id: str,
        generate_voice: bool = False,
        voice_settings: Optional[Dict] = None,
        system_prompt: Optional[str] = None,
        include_emotion: bool = False,
        **kwargs
    ) -> Dict[str, Any]:
        """
        处理聊天请求（保持原有返回格式不变）
        
        Args:
            messages: 消息列表
            session_id: 会话ID
            generate_voice: 是否生成语音
            voice_settings: 语音设置
            system_prompt: 系统提示词
            include_emotion: 是否包含情感分析
            **kwargs: 其他参数
            
        Returns:
            Dict[str, Any]: 聊天响应（格式与原版本完全一致）
        """
        try:
            # 调用LLM API获取响应前，打印完整请求参数
            request_params = {
                "messages": messages,
                "system_prompt": system_prompt,
                "temperature": kwargs.get('temperature', settings.temperature),
                "max_tokens": kwargs.get('max_tokens', settings.max_tokens),
                "stream": False,
                **kwargs
            }
            logger.info(f"[通义千问] chat_completion请求参数: {json.dumps(request_params, ensure_ascii=False, indent=2)}")
            # 调用LLM API获取响应
            llm_response = await self.llm_client.chat_completion(
                messages=messages,
                system_prompt=system_prompt,
                **kwargs
            )
            
            # 提取文本内容
            full_response = self.llm_client.extract_content_from_response(llm_response)
            
            # 处理情感分析
            emotions = {}
            extracted_emotion = "neutral"
            
            # 先提取情绪标识（用于TTS）
            from ..utils.qinxus_optimizer import extract_emotion_tag
            clean_text, tts_emotion = extract_emotion_tag(full_response)
            logger.info(f"[情绪识别] 非流式-原始回复: {full_response}")
            logger.info(f"[情绪识别] 非流式-提取到的情绪: {tts_emotion}")
            
            if include_emotion and full_response:
                # 如果开启情感分析，还需要提取qinxus情感（用于返回给前端）
                from ..utils.qinxus_optimizer import extract_qinxus_emotion_optimized
                clean_text, extracted_emotion = extract_qinxus_emotion_optimized(clean_text)
                full_response = clean_text
                emotions = {extracted_emotion: 1.0}
            else:
                # 只清理文本，不提取qinxus情感
                from ..utils.text_processor import clean_response_text
                full_response = clean_response_text(clean_text)
                emotions = {"neutral": 1.0}
            
            # 并行处理语音生成（如果需要）
            audio_response = None
            if generate_voice and full_response:
                audio_response = await self._generate_voice(
                    text=full_response,
                    emotion=tts_emotion,  # 使用从回复中提取的情绪
                    voice_settings=voice_settings
                )
            
            # 构建历史记录（保持原格式）
            history = [{"role": msg["role"], "content": msg["content"]} for msg in messages]
            
            # 返回格式严格保持与原版本一致
            return {
                "text": full_response,
                "audio": audio_response,
                "qx": emotions,  # 保持原字段名"qx"
                "session_id": session_id,
                "history": history
            }
            
        except Exception as e:
            logger.error(f"聊天处理失败: {e}", exc_info=True)
            # 返回错误情况下的默认响应
            return {
                "text": "抱歉，我现在无法回答您的问题，请稍后再试。",
                "audio": None,
                "qx": {"neutral": 1.0},
                "session_id": session_id,
                "history": [{"role": msg["role"], "content": msg["content"]} for msg in messages]
            }
    
    async def process_stream_chat(
        self,
        messages: List[Dict[str, str]],
        session_id: str,
        generate_voice: bool = False,
        voice_settings: Optional[Dict] = None,
        system_prompt: Optional[str] = None,
        include_emotion: bool = False,
        memory_service = None,
        **kwargs
    ) -> AsyncGenerator[Dict[str, Any], None]:
        """
        处理流式聊天请求
        
        Args:
            messages: 消息列表
            session_id: 会话ID
            generate_voice: 是否生成语音
            voice_settings: 语音设置
            system_prompt: 系统提示词
            include_emotion: 是否包含情感分析
            memory_service: 内存服务实例，用于保存历史记录
            **kwargs: 其他参数
            
        Yields:
            Dict[str, Any]: 流式响应数据
        """
        full_response = ""
        
        try:
            # 发送开始事件
            yield {
                "type": "start",
                "data": {
                    "session_id": session_id,
                    "timestamp": asyncio.get_event_loop().time()
                }
            }
            
            # 流式聊天前，打印完整请求参数
            stream_request_params = {
                "messages": messages,
                "system_prompt": system_prompt,
                "temperature": kwargs.get('temperature', settings.temperature),
                "max_tokens": kwargs.get('max_tokens', settings.max_tokens),
                "stream": True,
                **kwargs
            }
            logger.info(f"[通义千问] chat_stream请求参数: {json.dumps(stream_request_params, ensure_ascii=False, indent=2)}")
            
            # 先收集完整的LLM响应（不流式发送文本）
            async for chunk in self.llm_client.chat_stream(
                messages=messages,
                system_prompt=system_prompt,
                **kwargs
            ):
                # 提取增量文本
                delta_text = self.llm_client.extract_content_from_response(chunk)
                
                if delta_text:
                    full_response += delta_text
            
            # 处理完整响应的情感分析
            emotions = {}
            extracted_emotion = "neutral"
            
            # 先提取情绪标识（用于TTS）
            from ..utils.qinxus_optimizer import extract_emotion_tag
            clean_text, tts_emotion = extract_emotion_tag(full_response)
            logger.info(f"[情绪识别] 流式-原始回复: {full_response}")
            logger.info(f"[情绪识别] 流式-提取到的情绪: {tts_emotion}")
            
            if include_emotion and full_response:
                # 如果开启情感分析，还需要提取qinxus情感（用于返回给前端）
                from ..utils.qinxus_optimizer import extract_qinxus_emotion_optimized
                clean_text, extracted_emotion = extract_qinxus_emotion_optimized(clean_text)
                full_response = clean_text
                emotions = {extracted_emotion: 1.0}
            else:
                # 只清理文本，不提取qinxus情感
                from ..utils.text_processor import clean_response_text
                full_response = clean_response_text(clean_text)
                emotions = {"neutral": 1.0}
            
            # 1. 优先处理流式语音生成（如果需要）
            if generate_voice and full_response:
                try:
                    # 发送语音开始事件
                    yield {
                        "type": "audio_start",
                        "data": {"status": "generating"}
                    }
                    
                    # 流式生成语音
                    async for audio_chunk in self.tts_service.text_to_speech_stream(
                        text=full_response,
                        emotion=tts_emotion,  # 使用从回复中提取的情绪
                        voice_id=voice_settings.get("voice_id", "female-tianmei") if voice_settings else "female-tianmei",
                        speed=voice_settings.get("speed", 1.0) if voice_settings else 1.0,
                        vol=voice_settings.get("vol", 1.0) if voice_settings else 1.0,
                        pitch=voice_settings.get("pitch", 0) if voice_settings else 0,
                        language_boost=voice_settings.get("language_boost", "auto") if voice_settings else "auto",
                        timber_weights=voice_settings.get("timber_weights") if voice_settings else None
                    ):
                        # 发送流式音频块
                        yield {
                            "type": "audio_chunk",
                            "data": audio_chunk["data"]
                        }
                    
                    # 发送音频完成事件
                    yield {
                        "type": "audio_complete",
                        "data": {
                            "session_id": session_id,
                            "status": "completed"
                        }
                    }
                    
                except Exception as e:
                    logger.error(f"语音生成失败: {e}")
                    yield {
                        "type": "audio_error",
                        "data": {"error": str(e)}
                    }
            
            # 2. 然后流式发送文本内容
            # 将完整文本分块流式发送
            chunk_size = 5  # 每次发送5个字符
            for i in range(0, len(full_response), chunk_size):
                chunk_text = full_response[i:i + chunk_size]
                accumulated_text = full_response[:i + len(chunk_text)]
                
                yield {
                    "type": "text_delta",
                    "data": {
                        "delta": chunk_text,
                        "accumulated": accumulated_text
                    }
                }
                
                # 添加小延迟以模拟流式传输
                await asyncio.sleep(0.1)
            
            # 发送情感分析结果
            yield {
                "type": "emotion",
                "data": {
                    "emotion": extracted_emotion,
                    "scores": emotions
                }
            }
            
            # 发送完成事件 - 保持与原版本格式一致
            yield {
                "type": "message",
                "data": {
                    "text": full_response,
                    "qx": emotions,
                    "session_id": session_id,
                    "history": [{"role": msg["role"], "content": msg["content"]} for msg in messages]
                }
            }
            
            # 发送结束标识
            yield {
                "type": "done",
                "data": {
                    "done": True,
                    "session_id": session_id
                }
            }
            
            # 将Assistant的完整回复保存到历史记录中
            if memory_service and full_response:
                memory_service.add_message(session_id, "assistant", full_response)
            
        except Exception as e:
            logger.error(f"流式聊天处理失败: {e}", exc_info=True)
            yield {
                "type": "error",
                "data": {"error": str(e)}
            }
    
    async def _generate_voice(
        self,
        text: str,
        emotion: str = "neutral",
        voice_settings: Optional[Dict] = None
    ) -> Optional[Dict[str, Any]]:
        """
        生成语音（内部方法）
        
        Args:
            text: 要转换的文本
            emotion: 情感
            voice_settings: 语音设置
            
        Returns:
            Optional[Dict]: 语音数据，失败时返回None
        """
        try:
            # 构建TTS参数
            tts_params = {
                "text": text,
                "model": settings.default_tts_model,
                "voice_id": settings.default_voice_id,
                "speed": 1.0,
                "vol": 1.0,
                "pitch": 0,
                "stream": False,
                "language_boost": "auto",
                "emotion": emotion
            }
            
            # 应用自定义语音设置
            if voice_settings:
                for key in ["voice_id", "speed", "vol", "pitch", "language_boost", "timber_weights", "voice_model"]:
                    if key in voice_settings:
                        if key == "voice_model":
                            tts_params["model"] = voice_settings["voice_model"]
                        else:
                            tts_params[key] = voice_settings[key]
                # 覆盖情绪设置（如果指定）
                if voice_settings.get("emotion"):
                    tts_params["emotion"] = voice_settings["emotion"]
            
            # 调用TTS服务
            return await self.tts_service.text_to_speech(**tts_params)
            
        except Exception as e:
            logger.error(f"语音生成失败: {e}")
            return None
    
    async def close(self):
        """关闭服务，释放资源"""
        try:
            await self.tts_service.close()
            logger.info("聊天服务已关闭")
        except Exception as e:
            logger.error(f"关闭聊天服务时出错: {e}")


# 全局聊天服务实例
chat_service = ChatService() 